package com.north.light.libmusicplayerx.impl

import android.content.Context
import android.content.res.AssetFileDescriptor
import android.media.MediaPlayer
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.north.light.libmusicplayerx.api.LibPXMusicApi
import com.north.light.libmusicplayerx.listener.LibPXMusicEventListener
import com.north.light.libmusicplayerx.listener.LibPXMusicProgressListener
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicBoolean

/**
 * FileName: LibPXMusicMediaPlayerImpl
 * Author: lzt
 * Date: 2023/2/2 11:04
 */
class LibPXMusicMediaPlayerImpl : LibPXMusicApi {
    private val TAG = LibPXMusicMediaPlayerImpl::class.simpleName

    //监听集合
    private val mProgressListener: CopyOnWriteArrayList<LibPXMusicProgressListener> =
        CopyOnWriteArrayList()
    private val mEventListener: CopyOnWriteArrayList<LibPXMusicEventListener> =
        CopyOnWriteArrayList()

    //外部传入context
    private lateinit var mContext: Context

    //media player
    private lateinit var mPlayer: MediaPlayer

    //通知handler
    private var mUiHandler: Handler? = null

    //是否已经初始化
    private val mInit: AtomicBoolean = AtomicBoolean(false)

    //当前播放url
    private var mCurrentUrl: String? = null

    //timer task
    private var mTimer: Timer? = null
    private var mTimerTask: TimerTask? = null

    private fun isInit(): Boolean {
        if (!mInit.get()) {
            //通知外部需要初始化
            mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_NOT_INIT)
        }
        return mInit.get()
    }


    override fun init(context: Context) {
        mContext = context.applicationContext
        mPlayer = MediaPlayer()
        mPlayer.setOnPreparedListener(object : MediaPlayer.OnPreparedListener {
            override fun onPrepared(mp: MediaPlayer?) {
                mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_PLAY)
            }
        })
        mPlayer.setOnCompletionListener(object : MediaPlayer.OnCompletionListener {
            override fun onCompletion(mp: MediaPlayer?) {
                mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_COMPLETE)
            }
        })
        mPlayer.setOnBufferingUpdateListener(object : MediaPlayer.OnBufferingUpdateListener {
            override fun onBufferingUpdate(mp: MediaPlayer?, percent: Int) {
                Log.d(TAG, "play event: buffer $percent")
                mProgressListener.forEach { e -> e.buffering(mCurrentUrl, percent, 100) }
            }
        })
        mUiHandler = Handler(Looper.getMainLooper()) {
            when (it.what) {
                LibPXMusicHandlerParams.HANDLER_NOT_INIT -> {
                    //初始化
                    mEventListener.forEach { e -> e.needToInit() }
                    Log.d(TAG, "play event: need init")
                }
                LibPXMusicHandlerParams.HANDLER_PLAY -> {
                    //开始播放
                    mPlayer.start()
                    mEventListener.forEach { e -> e.play(mCurrentUrl) }
                    Log.d(TAG, "play event: need start")
                }
                LibPXMusicHandlerParams.HANDLER_COMPLETE -> {
                    //播放完成
                    mEventListener.forEach { e ->
                        e.finish(mCurrentUrl)
                        e.stop(mCurrentUrl)
                    }
                    Log.d(TAG, "play event: need finish")
                }
                LibPXMusicHandlerParams.HANDLER_PAUSE -> {
                    mEventListener.forEach { e -> e.pause(mCurrentUrl) }
                    Log.d(TAG, "play event: pause")
                }
                LibPXMusicHandlerParams.HANDLER_RESUME -> {
                    mEventListener.forEach { e -> e.resume(mCurrentUrl) }
                    Log.d(TAG, "play event: resume")
                }
                LibPXMusicHandlerParams.HANDLER_STOP -> {
                    mEventListener.forEach { e -> e.stop(mCurrentUrl) }
                    Log.d(TAG, "play event: stop")
                }
            }
            return@Handler false
        }
        //定时任务
        mTimerTask?.cancel()
        mTimer?.cancel()
        mTimer = Timer()
        mTimerTask = object : TimerTask() {
            override fun run() {
                if (!isPlaying()) {
                    return
                }
                mUiHandler?.post(Runnable {
                    mProgressListener.forEach { e ->
                        e.progress(mCurrentUrl, getProgress(), getDuration())
                    }
                })
            }
        }
        mTimer?.schedule(mTimerTask, 0, 1000)
        mInit.set(true)
    }

    override fun play(url: String) {
        if (!isInit()) {
            return
        }
        stop()
        mCurrentUrl = url
        mPlayer.reset()
        mPlayer.setDataSource(url)
        mPlayer.prepareAsync()
    }

    override fun playAsset(resId: String) {
        if (!isInit()) {
            return
        }
        stop()
        val assets = mContext.assets.openFd(resId)
        mCurrentUrl = resId
        mPlayer.reset()
        mPlayer.setDataSource(assets)
        mPlayer.prepareAsync()
    }

    override fun stop() {
        if (!isInit()) return
        mPlayer.stop()
        mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_STOP)
    }

    override fun resume() {
        if (!isInit()) return
        mPlayer.start()
        mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_RESUME)
    }

    override fun pause() {
        if (!isInit()) return
        mPlayer.pause()
        mUiHandler?.sendEmptyMessage(LibPXMusicHandlerParams.HANDLER_PAUSE)
    }

    override fun release() {
        if (!isInit()) return
        mInit.set(false)
        mPlayer.release()
        mUiHandler?.removeCallbacksAndMessages(null)
    }

    override fun isPlaying(): Boolean {
        return if (!isInit()) false else mPlayer.isPlaying
    }

    override fun seekTo(progress: Int) {
        if (!isInit()) return else mPlayer.seekTo(progress)
    }

    override fun getProgress(): Int {
        return if (!isInit()) 0 else mPlayer.currentPosition
    }

    override fun getDuration(): Int {
        return if (!isInit()) 0 else mPlayer.duration
    }

    override fun setProgressListener(listener: LibPXMusicProgressListener) {
        mProgressListener.add(listener)
    }

    override fun removeProgressListener(listener: LibPXMusicProgressListener) {
        mProgressListener.remove(listener)
    }

    override fun setEventListener(listener: LibPXMusicEventListener) {
        mEventListener.add(listener)
    }

    override fun removeEventListener(listener: LibPXMusicEventListener) {
        mEventListener.remove(listener)
    }
}